<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Hello world</title>
  <style>
  * {
    margin: 0;
    padding: 0;
  }

  .box {
    position: fixed;
    top: 50%;
    left: 50%;
    margin-top: -40vh;
    margin-left: -40vw;
    width: 80vw;
    height: 80vh;
  }

  .edit-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    z-index: -10;
    opacity: 0;
    /*z-index: 10;
    opacity: 1;*/
    width: 100%;
    height: 100%;
    background: #000;
    overflow: hidden;
  }

  .edit-wrapper.is-show {
    z-index: 10;
    opacity: 1;
  }

  .edit-content {
    position: absolute;
    z-index: 10;
    opacity: 1;
    top: 50%;
    left: 50%;
    transform-origin: center;
  }

  .aa {
    width: 100%;
    height: 100%;
    opacity: 1;
  }
  .btn-box {
    position: fixed;
    top: 40px;
    left: 40px;
    z-index: 10;
  }

  .right-menu {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1000;
    background: #fff;
    border-radius: 6px;
    padding: 6px 0;
    border: 1px solid #DCDFE6;
  }
  .right-menu.del .item {
    padding: 0 20px;
    line-height: 34px;
    cursor: pointer;
    min-width: 100px;
  }
  .right-menu.del .item:hover {
    background: #F5F7FA;
  }
  .right-menu.add .title {
    font-size: 16px;
    padding-left: 10px;
    color: #000;
    font-weight: bold;
    text-align: left;
}
.right-menu.add .list {
    max-width: 300px;
}
.right-menu.add .list:after {
    content: '';
    display: block;
    clear: both;
}
.right-menu.add .list .item {
    float: left;
    padding: 0 10px;
    line-height: 34px;
    cursor: pointer;
}
.right-menu.add .list .item:hover {
    font-weight: bold;
}
.right-menu.add .new {
    display: flex;
    pag: 10px;
    padding: 0 10px;
}
  </style>
</head>

<body>
  <div class="btn-box">
    <button onclick="showEditClick()">显示</button>
    <button onclick="hideEdit()">隐藏</button>
  </div>
  <div class="box">
    <div class="aa"></div>
    <div class="edit-wrapper">
      <div class="edit-content">
        <div style="width:100%; height:100%;" class="imageContainer"></div>
      </div>
    </div>
  </div>

<div class="right-menu del">
  <div class="item">删除</div>
</div>
<div class="right-menu add">
  <div class="title">添加</div>
  <div class="list"></div>
  <div class="new">
    <input type="text" placeholder="自定义类型"/>
    <button class="btn">确定</button>
  </div>
</div>

  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  <script src="./static/hammer.js"></script>
  <script src="./static/cornerstone.min.js"></script>
  <script src="./static/cornerstoneMath.min.js"></script>
  <script src="./static/cornerstoneWADOImageLoader.min.js"></script>
  <script src="./static/cornerstoneWebImageLoader.min.js"></script>
  <script src="./static/cornerstoneTools.min.js"></script>
  <script src="./static/dicomParser.min.js"></script>
  <script src="./static/addMouseWheel.js"></script>
  <script>
  const baseUrl = "http://127.0.0.1:8000/static/js/";
  const image_uir = '111'

  var config = {
      "胸膜增厚": "rgb(255, 0, 255)",
      "纤维灶": "rgb(220, 20, 60)",
      "钙化": "rgb(148, 0, 211)",
      "骨折": "rgb(123, 104, 238)",
      "肺不张": "rgb(0, 0, 205)",
      "肿块": "rgb(30, 144, 255)",
      "结节": "rgb(184, 134, 11)",
      "肺气肿": "rgb(0, 139, 0)",
      "气胸": "rgb(139, 35, 35)",
      "PICC": "rgb(218, 165, 32)",
      "积液": "rgb(255, 140, 0)",
      "积气": "rgb(0, 0, 0)",
      "实变": "rgb(85, 107, 47)",
      "术后金属": "rgb(95, 158, 160)",
      "膈下游离气体": "rgb(9,113,175)",
      "肠道积气扩张": "rgb(4,248,194)",
      "肠道积液液平": "rgb(148, 0, 211)",
      "泌尿系统结石": "rgb(108,227,33)"
  }



  var infos = {
        '111_ctr': {
          center_x: 1277,
          heart_x_begin_left: 936,
          heart_x_end_right: 2100,
          heart_y_begin_left: 1531,
          heart_y_end_right: 1621,
          lung_x_begin: 170,
          lung_x_end: 2348,
          lung_y: 1565,
          ratio: 0.5344,
        },
        '111_current': [{
          "name": "纤维灶",
          mark: true,
          "confidence": 1.0,
          "xmin": 1791.5301292590002,
          "ymin": 1144.1843983500526,
          "xmax": 2205.530129259,
          "ymax": 1429.1843983500526
        }, {
          "name": "结节",
          mark: true,
          "confidence": 1.0,
          "xmin": 1685.046367851623,
          "ymin": 668.259659969088,
          "xmax": 1751.046367851623,
          "ymax": 733.259659969088
        }, {
          "name": "实变",
          mark: true,
          "confidence": 1.0,
          "xmin": 1211.2967542503864,
          "ymin": 895.5332302936631,
          "xmax": 1613.2967542503864,
          "ymax": 1159.533230293663
        }, {
          "name": "结节",
          mark: true,
          "confidence": 1.0,
          "xmin": 902.8114374034003,
          "ymin": 814.0710973724885,
          "xmax": 1049.8114374034003,
          "ymax": 964.0710973724885
        }]
      }

  window.onload = function() {
    _initCornerstone();

    aaInitCornerstone();


    // 隐藏右键菜单
    $(window).on('click', () => {
      $('.right-menu').hide();
    })

    setDownList();

    // 绑定删除事件
    $('.right-menu.del').on('click', '.item', () => {
        oEdit.deleteRectData();
    })
  }

  function _initCornerstone() {
    cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
    cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
    cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
    cornerstoneTools.external.cornerstone = cornerstone;
    cornerstoneTools.external.Hammer = Hammer;

    // Image Loader
    const config = {
      webWorkerPath: `${baseUrl}assets/image-loader/cornerstoneWADOImageLoaderWebWorker.js`,
      taskConfiguration: {
        decodeTask: {
          codecsPath: `${baseUrl}assets/image-loader/cornerstoneWADOImageLoaderCodecs.js`,
        },
      },
    };
    cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
  }

  // 初始化影像
  function aaInitCornerstone() {
    let element = document.querySelector('.aa');
    cornerstone.enable(element);
    cornerstone.loadAndCacheImage('wadouri:http://localhost:8001/static/data/1.2.840.1.19439.0.1000.20220101135814.1480.10000.3383824/1.2.840.113564.12312312366.2022010113510529628.1003000225002').then(function(image) {

      var viewport = cornerstone.getDefaultViewportForImage(element, image);
      cornerstone.displayImage(element, image, viewport);
    });
    element.addEventListener('cornerstoneimagerendered', onImageRendered);
  }

  function onImageRendered(e) {
    oEdit.init(e);
  }

  // 设置下拉框
  function setDownList() {
      let html = '';
      for(let key in config) {
          html += `<div class="item" data-key="${key}" style="color:${config[key]}">${key}</div>`;
      }
      $('.right-menu.add .list').html(html);
      $('.right-menu.add .list').on('click', '.item', function () {
          let key = this.dataset.key;
          oEdit.addRect(key);
      })
      $('.right-menu.add .new').on('click', function (e) {
          e.stopPropagation();
      })
      $('.right-menu.add .new').on('click', '.btn', function (e) {
        let key = $('.right-menu.add .new input').val();
        oEdit.addRect(key);
        $('.right-menu.add').hide();
      })
  }

  // 显示编辑线
  function showEditClick() {
    oEdit.show({
      data: {
        line: infos[image_uir + '_ctr'],
        rect: infos[image_uir + '_current']
      },
      showLine: true
    });
  }


  // 隐藏
  function hideEdit() {
    oEdit.close();
  }


  const oEdit = {
    visible: false,

    oWrapper: $('.edit-wrapper'),
    oPosition: $('.edit-wrapper .edit-position'),
    oContent: $('.edit-wrapper .edit-content'),
    oContainer: $('.edit-wrapper .imageContainer'),
    oTarget: null,
    oCanvas: null,
    context: null,

    // 是否添加矩形
    isAddRect: false,
    add: {
        name: '',
        top: 0,
        left: 0,
        downx: 0,
        downy: 0,
        xmin: 0,
        ymin: 0,
        xmax: 0,
        ymax: 0,
    },

    // 删除下标
    deleteIndex: -1,

    // 图片数据
    image: {
      ratio: 0,
      leftDis: 0,
      topDis: 0,
      width: 0,
      height: 0,
      file: null
    },
    // 编辑类型，line线，rect方框
    editType: '',
    // 数据
    oldData: null,
    newData: null,
    startData: null,
    // 路径
    paths: [],
    oPath: null,
    // 滚动
    scale: 1,
    // 显示
    show(options) {
      this.setImagePosition();

      this.showLine = options.showLine; // 是否显示线
      this.oldData = JSON.parse(JSON.stringify(options.data));
      this.newData = JSON.parse(JSON.stringify(options.data));

      this.drawData();

      this.oWrapper.addClass('is-show');
      this.visible = true;
    },
    // 关闭
    close() {
      this.oWrapper.removeClass('is-show');
      this.visible = false;
    },
    // 初始化
    async init(e) {
      await this.initImageData(e);
      await waitTimeout(50);

      this.initEvent();
    },
    // 画
    addRect(name) {
        this.setImagePosition();
        this.oWrapper.addClass('is-show');

        this.isAddRect = true;
        this.add.name = name;
        // 绘图
        this.drawData(true);
        this.visible = true;
    },
    initEvent() {
      // 缩放大小
      addMouseWheel(this.oWrapper[0], (delta) => {
        let scale = this.scale;
        if(delta > 0) {
          scale += 0.05;
        } else if(delta < 0) {
          scale -= 0.05;
        }
        if(scale >= 2) {
          scale = 2;
        }
        if(scale <= this.image.ratio) {
          scale = this.image.ratio;
        }
        this.scale = scale;
        this.oContent.css({
          transform: `translate(-50%, -50%) scale(${scale})`
        })
      })

      // 拖动
      let cIsDown = false;
      let cdownx = 0, cdowny = 0;
      let startLeft = 0, startTop = 0;
      this.oWrapper.on('mousedown', (e) => {
        if(isDown) {
          return;
        }
        cIsDown = true;
        cdownx = e.pageX;
        cdowny = e.pageY;
        startLeft = parseInt(this.oContent.css('left'));
        startTop = parseInt(this.oContent.css('top'));
      })

      window.addEventListener('mousemove', (e) => {
        if(cIsDown) {
          var movex = e.pageX - cdownx + startLeft;
          var movey = e.pageY - cdowny + startTop;
          this.oContent.css({
            left: movex+'px',
            top: movey+'px'
          })
        }
      })


      var context = this.context;
      var isDown = false;
      var downx = 0, downy = 0;

      $(this.oCanvas).on('mousedown', (e) => {
        if(!this.visible) {
            return;
        }
        var canvas = this.oCanvas;
        var rect = canvas.getBoundingClientRect();
        var x = (e.clientX - rect.left) / this.scale;
        var y = (e.clientY - rect.top) / this.scale;
        if(this.isAddRect) {
            isDown = true;
            this.add.left = rect.left;
            this.add.top = rect.top;
            this.add.downx = e.pageX;
            this.add.downy = e.pageY;
        } else {
          this.paths.forEach((item) => {
            if(context.isPointInPath(item.path, x, y)) {
              this.oPath = item;
              isDown = true;
              this.startData = JSON.parse(JSON.stringify(this.newData));
              downx = e.pageX;
              downy = e.pageY;
            }
          })
        }
      })

      $(this.oCanvas).on('mousemove', (e) => {
        if(!this.visible) {
            return;
        }
        if(this.isAddRect && isDown) {
            let movex = (e.pageX - this.add.downx) / this.scale;
            let movey = (e.pageY - this.add.downy) / this.scale;
            this.add.xmin = (this.add.downx - this.add.left) / this.scale;
            this.add.ymin = (this.add.downy - this.add.top) / this.scale;
            this.add.xmax = (this.add.downx - this.add.left) / this.scale + movex;
            this.add.ymax = (this.add.downy - this.add.top) / this.scale + movey;
            this.drawData(true);
            this.drawAddRect();
        } else {
          // 如果当前是按下
          if(isDown) {
            var movex = (e.pageX - downx) / this.scale;
            var movey = (e.pageY - downy) / this.scale;
            if(this.oPath.type == 'line') {
              this.saveLineData(this.oPath.key, this.oPath.dir, movex, movey);
            } else if (this.oPath.type == 'rect') {
              this.saveRectData(this.oPath, movex, movey);
            }
          } else { // 非按下，移动改变canvas鼠标形状
            var canvas = this.oCanvas;
            var rect = canvas.getBoundingClientRect();
            var x = (e.clientX - rect.left) / this.scale;
            var y = (e.clientY - rect.top) / this.scale;
            for(var i = 0; i < this.paths.length; i++) {
              var item = this.paths[i];
              if(context.isPointInPath(item.path, x, y)) {
                canvas.style.cursor = item.cursor;
                break;
              } else {
                canvas.style.cursor = '';
              }
            }
          }
        }
      })

      window.addEventListener('mouseup', () => {
        if(!this.visible) {
            return;
        }
        cIsDown = false;
        isDown = false;
        // 如果是添加矩形，鼠标抬起后，绘制可拖拽数据
        if(this.isAddRect) {
          this.newData.rect.push({
            name: this.add.name,
            mark: true,
            confidence: 1.0,
            xmin: (this.add.xmin-this.image.leftDis),
            ymin: (this.add.ymin-this.image.topDis),
            xmax: (this.add.xmax-this.image.leftDis),
            ymax: (this.add.ymax-this.image.topDis),
          })
          this.isAddRect = false;
          oEdit.show({
            data: this.newData,
            showLine: true
          });
        }
      })

      // 右键弹出菜单
      this.oWrapper.on('contextmenu', 'canvas', (e) => {
        e.preventDefault();
        e.stopPropagation();
        var canvas = this.oCanvas;
        var rect = canvas.getBoundingClientRect();
        var x = (e.clientX - rect.left) / this.scale;
        var y = (e.clientY - rect.top) / this.scale;
        let i = -1;
        this.paths.forEach((item) => {
          if(context.isPointInPath(item.path, x, y)) {
            if(item.cursor == 'move') {
                i = item.index;
            }
          }
        })
        $('.right-menu').hide();
        if(i == -1) {
          $('.right-menu.add').css({
            top: e.pageY+'px',
            left: e.pageX+'px'
          })
          $('.right-menu.add').show();
        } else {
          $('.right-menu.del').css({
            top: e.pageY+'px',
            left: e.pageX+'px'
          })
          $('.right-menu.del').show();
          this.deleteIndex = i;
        }
      })
    },

    // 初始化图片宽高
    async initImageData(e) {
      var image = e.detail.image;

      // 保存图片宽高
      this.image.width = e.detail.image.width;
      this.image.height = e.detail.image.height;

      this.oTarget = e.target;
      this.image.ratio = e.detail.viewport.scale;
      
      this.setImagePosition();

      // 设置图片
      cornerstone.enable(this.oContainer[0]);
      var viewport = cornerstone.getDefaultViewportForImage(this.oContainer[0], image);
      cornerstone.displayImage(this.oContainer[0], image, viewport);
      await waitTimeout(50);

      // 获取ctx对象
      this.oCanvas = this.oContainer[0].children[0];
      this.context = this.oCanvas.getContext('2d');
      // 保存图片
      var base64 = this.oCanvas.toDataURL('image/png');
      var img = new Image();
      img.src = base64;
      img.onload = () => {
        this.image.file = img;
        this.image.leftDis = (img.width-this.image.width)/2;
        this.image.topDis = (img.height-this.image.height)/2;
      }
    },

    // 设置图片大小位置
    setImagePosition() {
      let ratio = this.image.ratio;
      // 设置宽高
      this.oContent.width(this.oTarget.clientWidth/ratio);
      this.oContent.height(this.oTarget.clientHeight/ratio);
      // 设置比例
      this.oContent.css({
        transform: `translate(-50%, -50%) scale(${ratio})`
      })
      // 设置缩放大小
      this.scale = ratio;
    },

    // 保存线数据
    saveLineData(key, dir, movex, movey) {
        let oLine = this.newData.line;
        let startLine = this.startData.line;
        // 保存线位置数据
        oLine[key] = (dir == 'x' ? movex : movey) + startLine[key];
        // 计算心胸比
        oLine.ratio = (oLine.heart_x_end_right - oLine.heart_x_begin_left) / (oLine.lung_x_end - oLine.lung_x_begin);

        // 画数据
        this.drawData();
    },

    // 保存矩形数据
    saveRectData(path, movex, movey) {
        let oRect = this.newData.rect;
        let startRect = this.startData.rect;
        var index = path.index;
        if(path.dir == 'xy') {
          if(path.key instanceof Array) {
            let xkey = path.key[0], ykey = path.key[1];
            oRect[index][xkey] = movex+startRect[index][xkey];
            oRect[index][ykey] = movey+startRect[index][ykey];                    
          } else {
            oRect[index].xmin = movex+startRect[index].xmin;
            oRect[index].xmax = movex+startRect[index].xmax;
            oRect[index].ymin = movey+startRect[index].ymin;
            oRect[index].ymax = movey+startRect[index].ymax;
          }
        } else {
            oRect[index][path.key] = (path.dir == 'x' ? movex : movey)+startRect[index][path.key];
        }

        // 画数据
        this.drawData();
    },

    // 删除数据
    deleteRectData() {
      this.newData.rect[this.deleteIndex].isDelete = true;
      this.drawData();
    },

    // 画数据
    drawData(onlyImg) {
        this.paths = [];
        // 清空画布
        this.oCanvas.width = this.oCanvas.width;
        // 绘制底图
        this.drawImage();
        // 画线，画框
        this.drawRect(this.newData.rect, onlyImg);
        if(this.showLine) {
            this.drawLine(this.newData.line, onlyImg);
        }
    },

    // 绘制底图
    drawImage() {
      this.context.drawImage(this.image.file,0,0);
    },

    // 画线
    drawLine(data, onlyImg) {
      var ctr = {
        lung_x_begin: data.lung_x_begin+this.image.leftDis,
        lung_x_end: data.lung_x_end+this.image.leftDis,
        lung_y: data.lung_y+this.image.topDis,
        heart_x_begin_left: data.heart_x_begin_left+this.image.leftDis,
        heart_x_end_right: data.heart_x_end_right+this.image.leftDis,
        heart_y_begin_left: data.heart_y_begin_left+this.image.topDis,
        heart_y_end_right: data.heart_y_end_right+this.image.topDis,
      };
      var context = this.context;
      var paths = [];

      var path = null;

      let size1 = 15;
      let size2 = 20;
      let size3 = 8;
      let size4 = 50;

      context.beginPath();
      context.lineWidth = size1;
      context.strokeStyle = "green"
      context.moveTo(ctr.lung_x_begin, ctr.lung_y);
      context.lineTo(ctr.lung_x_end, ctr.lung_y);
      context.closePath();
      context.stroke();

      centerX = (ctr.lung_x_begin + ctr.lung_x_end) / 2
      Y = [ctr.lung_y, ctr.heart_y_begin_left, ctr.heart_y_end_right]
      minY = Math.min(...Y)
      maxY = Math.max(...Y)
      context.strokeStyle = "black"
      context.beginPath();
      context.moveTo(centerX, minY - size4);
      context.lineTo(centerX, maxY + size4);
      context.closePath();
      context.stroke();

      context.strokeStyle = "red"
      context.beginPath();
      context.moveTo(ctr.heart_x_begin_left, ctr.heart_y_begin_left);
      context.lineTo(centerX, ctr.heart_y_begin_left);
      context.closePath();
      context.stroke();

      context.beginPath();
      context.moveTo(centerX, ctr.heart_y_end_right);
      context.lineTo(ctr.heart_x_end_right, ctr.heart_y_end_right);
      context.closePath();
      context.stroke();
    
      if(!onlyImg) {
        // ------------------------------
        // 绿色左
        context.beginPath();
        context.arc(ctr.lung_x_begin, ctr.lung_y, size3*2, 0, 2*Math.PI);
        context.closePath();
        context.lineWidth = size3;
        context.strokeStyle = '#ffffff';
        context.stroke();
        // 添加路径
        path = new Path2D();
        path.arc(ctr.lung_x_begin, ctr.lung_y, size3*2, 0, 2*Math.PI);
        paths.push({
          type: 'line',
          cursor: 'e-resize',
          dir: 'x',
          path: path,
          key: 'lung_x_begin'
        });
        // 绿色右
        context.beginPath();
        context.arc(ctr.lung_x_end, ctr.lung_y, size3*2, 0, 2*Math.PI);
        context.closePath();
        context.lineWidth = size3;
        context.strokeStyle = '#ffffff';
        context.stroke();
        // 添加路径
        path = new Path2D();
        path.arc(ctr.lung_x_end, ctr.lung_y, size3*2, 0, 2*Math.PI);
        paths.push({
          type: 'line',
          cursor: 'e-resize',
          dir: 'x',
          path: path,
          key: 'lung_x_end'
        });
        // 绿色中
        context.beginPath();
        context.arc(ctr.lung_x_begin+(ctr.lung_x_end-ctr.lung_x_begin)/2, ctr.lung_y, size3*2, 0, 2*Math.PI);
        context.closePath();
        context.lineWidth = size3;
        context.strokeStyle = '#ffffff';
        context.stroke();
        // 添加路径
        path = new Path2D();
        path.arc(ctr.lung_x_begin+(ctr.lung_x_end-ctr.lung_x_begin)/2, ctr.lung_y, size3*2, 0, 2*Math.PI);
        paths.push({
          type: 'line',
          cursor: 'n-resize',
          dir: 'y',
          path: path,
          key: 'lung_y'
        });


        // 红色左
        context.beginPath();
        context.arc(ctr.heart_x_begin_left, ctr.heart_y_begin_left, size3*2, 0, 2*Math.PI);
        context.closePath();
        context.lineWidth = size3;
        context.strokeStyle = '#ffffff';
        context.stroke();
        // 添加路径
        path = new Path2D();
        path.arc(ctr.heart_x_begin_left, ctr.heart_y_begin_left, size3*2, 0, 2*Math.PI);
        paths.push({
          type: 'line',
          cursor: 'e-resize',
          dir: 'x',
          path: path,
          key: 'heart_x_begin_left'
        });
        // 红色中
        context.beginPath();
        context.arc(ctr.heart_x_begin_left+(centerX-ctr.heart_x_begin_left)/2, ctr.heart_y_begin_left, size3*2, 0, 2*Math.PI);
        context.closePath();
        context.lineWidth = size3;
        context.strokeStyle = '#ffffff';
        context.stroke();
        // 添加路径
        path = new Path2D();
        path.arc(ctr.heart_x_begin_left+(centerX-ctr.heart_x_begin_left)/2, ctr.heart_y_begin_left, size3*2, 0, 2*Math.PI);
        paths.push({
          type: 'line',
          cursor: 'n-resize',
          dir: 'y',
          path: path,
          key: 'heart_y_begin_left'
        });

        // 红色右
        context.beginPath();
        context.arc(ctr.heart_x_end_right, ctr.heart_y_end_right, size3*2, 0, 2*Math.PI);
        context.closePath();
        context.lineWidth = size3;
        context.strokeStyle = '#ffffff';
        context.stroke();
        // 添加路径
        path = new Path2D();
        path.arc(ctr.heart_x_end_right, ctr.heart_y_end_right, size3*2, 0, 2*Math.PI);
        paths.push({
          type: 'line',
          cursor: 'e-resize',
          dir: 'x',
          path: path,
          key: 'heart_x_end_right'
        });
        // 红色中
        context.beginPath();
        context.arc(centerX+(ctr.heart_x_end_right-centerX)/2, ctr.heart_y_end_right, size3*2, 0, 2*Math.PI);
        context.closePath();
        context.lineWidth = size3;
        context.strokeStyle = '#ffffff';
        context.stroke();
        // 添加路径
        path = new Path2D();
        path.arc(centerX+(ctr.heart_x_end_right-centerX)/2, ctr.heart_y_end_right, size3*2, 0, 2*Math.PI);
        paths.push({
          type: 'line',
          cursor: 'n-resize',
          dir: 'y',
          path: path,
          key: 'heart_y_end_right'
        });
      }
      this.paths.push(...paths.reverse());
    },

    // 画矩形
    drawRect(data, onlyImg) {
        var list = data;
        var context = this.context;
        var paths = [];

        var path = null;

        for(var i = 0; i < list.length; i++) {
            var item = list[i];
            if(item.isDelete) {
              continue;
            }
            if(!item.mark) {
                continue;
            }
            var confidence = item.confidence;
            var label = item.name;
            var color = config[label] || 'rgb(0,0,0)';

            if (confidence !== 1) {
                label = label + " " + confidence;
            }
            var xmin = item.xmin+this.image.leftDis;
            var ymin = item.ymin+this.image.topDis;
            var xmax = item.xmax+this.image.leftDis;
            var ymax = item.ymax+this.image.topDis;

            var size1 = 60;
            var size2 = 8;
            var size3 = 4;

            context.fillStyle = color;
            context.strokeStyle = color;
            context.lineWidth = size2;
            context.font = size1+"px 微软雅黑"
            context.beginPath();
            context.moveTo(xmin, ymin);
            context.lineTo(xmin, ymax);
            context.lineTo(xmax, ymax);
            context.lineTo(xmax, ymin);
            context.lineTo(xmin, ymin);
            context.fillText(label, xmin, ymin - 1)
            context.fillRect(xmin, ymin - size1, context.measureText(label).width, size1);
            context.closePath();
            context.stroke();
            context.fillStyle = "white"
            context.fillText(label, xmin, ymin - 1);

            if(!onlyImg) {
              // 添加右下
              context.beginPath();
              context.arc(xmax, ymax, size2*2, 0, 2*Math.PI);
              context.closePath();
              context.lineWidth = size2;
              context.strokeStyle = '#ffffff';
              context.stroke();
              // 添加路径
              path = new Path2D();
              path.arc(xmax, ymax, size2*2, 0, 2*Math.PI);
              paths.push({
                  type: 'rect',
                  cursor: 'se-resize',
                  dir: 'xy',
                  path: path,
                  key: ['xmax', 'ymax'],
                  index: i
              });

              // 添加左上
              context.beginPath();
              context.arc(xmin, ymin, size2*2, 0, 2*Math.PI);
              context.closePath();
              context.lineWidth = size2;
              context.strokeStyle = '#ffffff';
              context.stroke();
              // 添加路径
              path = new Path2D();
              path.arc(xmin, ymin, size2*2, 0, 2*Math.PI);
              paths.push({
                  type: 'rect',
                  cursor: 'nw-resize',
                  dir: 'xy',
                  path: path,
                  key: ['xmin', 'ymin'],
                  index: i
              });

              let xysize = 16;

              // 添加中心
              var xcenter = xmin+(xmax-xmin)/2;
              var ycenter = ymin+(ymax-ymin)/2;
              context.beginPath();
              context.moveTo(xcenter-xysize, ycenter);
              context.lineTo(xcenter+xysize, ycenter);
              context.closePath();
              context.lineWidth = size2/2;
              context.strokeStyle = '#ffffff';
              context.stroke();
              context.beginPath();
              context.moveTo(xcenter, ycenter-xysize);
              context.lineTo(xcenter, ycenter+xysize);
              context.closePath();
              context.lineWidth = size2/2;
              context.strokeStyle = '#ffffff';
              context.stroke();
              //添加路径
              path = new Path2D();
              path.rect(xcenter-xysize, ycenter-xysize, xysize*2, xysize*2);
              paths.push({
                  type: 'rect',
                  cursor: 'move',
                  dir: 'xy',
                  path: path,
                  index: i
              });
            }
        }
        this.paths.push(...paths.reverse());
    },

    // 画添加矩形
    drawAddRect() {
        let xmin = this.add.xmin;
        let ymin = this.add.ymin;
        let xmax = this.add.xmax;
        let ymax = this.add.ymax;

        let label = this.add.name;
        let color = config[label] || 'rgb(0,0,0)';
        let context = this.context;

        var size1 = 60;
        var size2 = 8;
        var size3 = 4;

        context.fillStyle = color;
        context.strokeStyle = color;
        context.lineWidth = size2;
        context.font = size1+"px 微软雅黑"
        context.beginPath();
        context.moveTo(xmin, ymin);
        context.lineTo(xmin, ymax);
        context.lineTo(xmax, ymax);
        context.lineTo(xmax, ymin);
        context.lineTo(xmin, ymin);
        context.fillText(label, xmin, ymin - 1)
        context.fillRect(xmin, ymin - size1, context.measureText(label).width, size1);
        context.closePath();
        context.stroke();
        context.fillStyle = "white"
        context.fillText(label, xmin, ymin - 1);
    },

    // 获取图片
    getImageFile(data) {
        this.showLine = true; // 是否显示线
        this.oldData = JSON.parse(JSON.stringify(data));
        this.newData = JSON.parse(JSON.stringify(data));

        this.drawData();

        // 保存图片
        var base64 = this.oCanvas.toDataURL('image/png');
        return base64ToFile(base64, '数据.png');
    }
}


  const waitTimeout = function (time) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve();
      }, time);
    })
  }
  </script>
</body>

</html>